package org.dong.samples.aop;
import java.util.Arrays;
import java.util.Date;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LogAspect {
	
	public long atartTime;
	
	public long endTime;
	
	public static final String add = "execution(* org.dong.samples.web.UserSubjectController.add*(..))";
	
	public static final String edit = "execution(* org.dong.samples.web.UserSubjectController.edit*(..))";
	
	@Pointcut("execution(* org.dong.samples.web.*.*(..))")
	public void allMethod(){
		
	}
	 /**
     * 切面的前置方法 即方法执行前拦截到的方法 记录并输出
     * 在目标方法执行之前的通知
     * @param joinPoint
     */
	@Before("allMethod()")
	public void before(JoinPoint point){
		Date date = new Date();
		atartTime = date.getTime();
        System.out.println("——————————调用"+point.getSignature().getDeclaringTypeName()
				+ "."+point.getSignature().getName()+"——————————");
    }
	
	@After("allMethod()")
	public void after(JoinPoint point){
		Date date = new Date();
		endTime = date.getTime()-atartTime;
		System.out.println("——————————调用"+point.getSignature().getDeclaringTypeName()
				+ "."+point.getSignature().getName()+"结束——————————"+"用时"+endTime+"ms");
	}
	
	@After(add)
	public void afterLog(JoinPoint point){
		System.out.println("afterLog---------------最终通知");
		System.out.println("afterLog---------------目标方法为："
				+ point.getSignature().getDeclaringTypeName()
				+ "."+point.getSignature().getName());
		System.out.println("afterLog---------------参数为："+Arrays.toString(point.getArgs()));
		System.out.println("afterLog---------------被织入的目标对象为："+point.getTarget());
	}

	@AfterReturning(value = add, returning = "returnValue")
	public void AfterReturningLog(JoinPoint point, Object returnValue){
		System.out.println("AfterReturningLog---------------返回值后通知");
		System.out.println("AfterReturningLog---------------目标方法为："
				+point.getSignature().getDeclaringTypeName()
				+"."+point.getSignature().getName());
		System.out.println("AfterReturningLog---------------参数为："
				+Arrays.toString(point.getArgs()));
		System.out.println("AfterReturningLog---------------返回值:"+returnValue);
	}
	
	@AfterThrowing(throwing = "ex", value = add)
	public void AfterThrowing(Throwable ex){
		System.out.println("AfterThrowing---------------进入异常通知");
		System.out.println("AfterThrowing---------------异常信息："+ex.getMessage());
	}
	
	@Around(value = "allMethod()")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("Around---------------进入	环绕通知");
		Object obj = pjp.proceed();
		System.out.println("Around---------------结束方法调用");
		return obj;
	}
	
	
	@After(edit)
	public void afterLog2(JoinPoint point){
		System.out.println("afterLog---------------最终通知");
		System.out.println("afterLog---------------目标方法为："
				+ point.getSignature().getDeclaringTypeName()
				+ "."+point.getSignature().getName());
		System.out.println("afterLog---------------参数为："+Arrays.toString(point.getArgs()));
		System.out.println("afterLog---------------被织入的目标对象为："+point.getTarget());
	}

	@AfterReturning(value = edit, returning = "returnValue")
	public void AfterReturningLog2(JoinPoint point, Object returnValue){
		System.out.println("AfterReturningLog---------------返回值后通知");
		System.out.println("AfterReturningLog---------------目标方法为："
				+point.getSignature().getDeclaringTypeName()
				+"."+point.getSignature().getName());
		System.out.println("AfterReturningLog---------------参数为："
				+Arrays.toString(point.getArgs()));
		System.out.println("AfterReturningLog---------------返回值:"+returnValue);
	}
	
	@AfterThrowing(throwing = "ex", value = edit)
	public void AfterThrowing2(Throwable ex){
		System.out.println("AfterThrowing---------------进入异常通知");
		System.out.println("AfterThrowing---------------异常信息："+ex.getMessage());
	}
}
